/**
 * @(#)Controller.java
 * 
 * @title Controller
 * @author Aditya Lesmana
 * @date 12/01/2009
 * @version 1.00
 */

package controller;

import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import model.Model;

import org.mybeans.dao.DAOException;

import controller.Action;
import controller.CustomerViewAccountAction;
import controller.CustomerViewPaymentHistoryAction;
import controller.CustomerViewTransactionHistoryAction;
import controller.EmployeeViewCustomerAccountAction;
import controller.EmployeeViewCustomerTransactionHistoryAction;
import controller.EmployeeViewCustomerPaymentHistoryAction;


public class Controller extends HttpServlet {

    private static final long serialVersionUID = 1L;
    Model model;
    
    public void init() throws ServletException {
        
        model = new Model(getServletConfig());
        
        /* create table if it does not exist
        try {
            model.getUserDAO().createUserTable();
            model.getBookmarkDAO().createBookmarkTable();
        } catch (DAOException e) {
            System.out.println(e.getMessage());
            return;
        }
        */
        // Under Con controller
        Action.add(new UnderconAction(model));
        Action.add(new IndexAction(model));
        
        //Employee use cases
        Action.add(new EmployeeDashboardAction(model)); //see dashboard
        Action.add(new EmployeeLoginAction(model)); //login
        Action.add(new EmployeeLogoutAction(model));  //logout
        Action.add(new EmployeeChangePasswordAction(model)); //change password
        Action.add(new EmployeeCreateEmployeeAccountAction(model)); //create Employee
        Action.add(new EmployeeCreateCustomerAccountAction(model)); //create Employee
        Action.add(new EmployeeResetCustomerPasswordAction(model)); //reset customer password
        Action.add(new EmployeeCreateFundAction(model)); //add fund 
        Action.add(new EmployeeViewFundsAction(model)); //view funds
        Action.add(new EmployeeCreateFundHistoryAction(model)); //create fund History - possibly can be removed later after transition date is made
        Action.add(new EmployeeViewCustomerAccountAction(model));//view customer account
        Action.add(new EmployeeViewCustomerTransactionHistoryAction(model)); //view transaction history
        Action.add(new EmployeeViewCustomerPaymentHistoryAction(model)); //view payment history
        
        
        Action.add(new EmployeeDepositCheckAction(model));

        Action.add(new EmployeeExecuteTransitionAction(model)); //execute transition day

        Action.add(new EmployeeCustomerManagerAction(model)); //manage customer page
        
        //Customer use cases
        Action.add(new CustomerDashboardAction(model));
        Action.add(new CustomerLoginAction(model));//login
        Action.add(new CustomerLogoutAction(model));//logout
        Action.add(new CustomerChangePasswordAction(model));// change password
        Action.add(new CustomerBuyFundAction(model)); //buy fund
        Action.add(new CustomerSellFundAction(model));// sell fund
        Action.add(new CustomerViewAccountAction(model)); //view account
        Action.add(new CustomerViewTransactionHistoryAction(model)); //view transaction history
        Action.add(new CustomerViewPaymentHistoryAction(model)); //view payment history
        Action.add(new CustomerResearchFundAction(model));
        Action.add(new CustomerRequestCheckAction(model));
        Action.add(new CustomerViewPendingTransactionsAction(model));
        Action.add(new CustomerExchangeFundAction(model));
        
        Action.add(new CustomerViewFundsAction(model)); //view payment history

        // test action
        Action.add(new HelloWorldAction(model));
        Action.add(new TestSendEmailAction(model));
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (model.getRequireSSL() && !request.isSecure()) {
            // If we're required to use SSL and we're not on a secure connection, redirect
            String host = request.getServerName();
            String port = (request.getServerPort()==80) ? "" : ":8443";
            response.sendRedirect("https://"+host+port+request.getRequestURI());
            return;
        }

        String nextPage = performTheAction(request);
        if (nextPage != null) {
            if (nextPage.substring(0,7).equals("http://")) {
                sendOutPage(nextPage,request,response);
                return;
            }
            sendToNextPage(nextPage,request,response);
        }
    }
    
    /*
     * Extracts the requested action and (depending on whether the user is logged in)
     * perform it (or make the user login).
     * @param request
     * @return the next page (the view)
     */
    private String performTheAction(HttpServletRequest request) {

        String servletPath = request.getServletPath();
        String actionName  = getActionName(servletPath);
        
        //HttpSession session = request.getSession(true);
        //User user = (User) session.getAttribute("user"); //use this when there will access control in place

        //if any of this thing is true go to welcome screen
        if ((actionName == null) || (actionName.equals("")) || (actionName.equals("start"))) {
            //return Action.perform("helloWorld.do",request);
            return "index.do";
        }
        
        //TODO need to have some access control between authenticated user and non authenticated user
        
        return Action.perform(actionName, request);


    }
    
    private void sendToNextPage(String nextPage, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        
        if (nextPage == null) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND,request.getServletPath());
            return;
        }
        
        if (nextPage.charAt(0) == '/') {
            String proto = request.isSecure() ? "https://" : "http://";
            String host  = request.getServerName();
            String port  = ":"+String.valueOf(request.getServerPort());
            if (port.equals(":80")) port = "";
            if (port.equals(":443")) port = "";
            String context = request.getContextPath();
            int lastSlash = context.lastIndexOf('/');
            String prefix = ( lastSlash==0 ? context : context.substring(0,lastSlash) );
            response.sendRedirect(proto+host+port+prefix+nextPage);
            return;
        }
        
        RequestDispatcher d = request.getRequestDispatcher("/view/"+nextPage);
        d.forward(request,response);
    }
    
    private void sendOutPage(String nextPage, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        
        response.sendRedirect(nextPage);
    }

    /*
     * Returns the path component after the last slash
     */
    private String getActionName(String path) {
        int slash = path.lastIndexOf('/');
        return path.substring(slash+1);
    }
    
}
